package cn.nawang.ebeim.api.service.impl;

import java.util.Date;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import cn.nawang.ebeim.api.domain.Ca;
import cn.nawang.ebeim.api.domain.ShortMessage;
import cn.nawang.ebeim.api.domain.User;
import cn.nawang.ebeim.api.repository.CaRepository;
import cn.nawang.ebeim.api.repository.UserRepository;
import cn.nawang.ebeim.api.repository.impl.CaQueryRepositoryImpl;
import cn.nawang.ebeim.api.repository.impl.UserQueryImpl;
import cn.nawang.ebeim.api.service.AuthorizationCheckService;
import cn.nawang.ebeim.api.utils.Constant;
import cn.nawang.ebeim.api.utils.DateUtils;
import cn.nawang.ebeim.api.utils.JsonUtil;
import cn.nawang.ebeim.api.utils.ValidateUtil;
import cn.nawang.ebeim.verification.SmsVerification;

/**
 * @ClassName: AuthorizationCheckServiceImpl
 * @Description: TODO
 * @author fanyb
 * @date Oct 26, 2015 8:22:44 PM
 * @version v1.0
 */
@Service("authorizationCheckService")
public class AuthorizationCheckServiceImpl implements AuthorizationCheckService {

  @Autowired
  private UserQueryImpl userQueryImpl;
  @Autowired
  private UserRepository userRepository;
  @Autowired
  private CaQueryRepositoryImpl caQueryRepositoryImpl;
  @Autowired
  private CaRepository caRepository;

  @Override
  public Map<String, Object> authorizationCheck(Map<String, Object> map, String username,
      String code, String bindDevice, String bindDeviceName, String key) {
    // 1.获取用户对象
    User user = userQueryImpl.findUserByUsername(username);
    // 2.验证授权方式
    String labType = user.getLabType();
    String isFirstLogin = user.getIsFirstLogin();
    if (Constant.LAB_TYPE_ZERO.equals(labType)) {// 无授权方式
      noAuthorizetionCheck(map, username);
    } else if (Constant.LAB_TYPE_ONE.equals(labType)
        && Constant.USER_IS_FIRST_LOGIN_YES.equals(isFirstLogin)) {// key无关联
      keyNoBindCheck(map, username, code, key);
    } else if (Constant.LAB_TYPE_TWO.equals(labType)
        && Constant.USER_IS_FIRST_LOGIN_YES.equals(isFirstLogin)) {// 授权码无关联
      authorizationCodeNoBindCheck(map, username, code);
    } else if (Constant.LAB_TYPE_THREE.equals(labType)) {// key关联设备
      keyBindCheck(map, username, code, bindDevice, bindDeviceName, key);
    } else if (Constant.LAB_TYPE_FOUR.equals(labType)) {// 授权码关联设备
      authorizationCodeBindCheck(map, username, code, bindDevice, bindDeviceName);
    }
    return map;
  }

  @Override
  public boolean noAuthorizetionCheck(Map<String, Object> map, String username) {
    // 获取登陆对象
    User user = userQueryImpl.findUserByUsername(username);
    user.setIsFirstLogin(Constant.USER_IS_FIRST_LOGIN_NO);
    userRepository.save(user);
    // 无授权直接通过
    map.put("code", Constant.CODE_SUCCESS);
    map.put("desc", "授权验证通过");
    return true;
  }

  @Override
  public boolean keyNoBindCheck(Map<String, Object> map, String username, String code, String key) {
    // 获取登陆对象
    User user = userQueryImpl.findUserByUsername(username);
    // 判断网络是否连通着的
    if (!isNetWorking(map)) {
      return false;
    }
    // 判断是否插入key
    if (!isExistKey(map, user, key)) {
      return false;
    }
    // 使用用户的手机号码进行短信验证
    if (!isShortMessageCheck(map, user, code)) {
      return false;
    }
    // 验证通过修改首次登陆状态以及授权时间和过期时间的设定
    if (!updateFirstLogin(map, user)) {
      return false;
    }
    return true;
  }

  @Override
  public boolean keyBindCheck(Map<String, Object> map, String username, String code,
      String bindDevice, String bindDeviceName, String key) {
    // 获取登陆对象
    User user = userQueryImpl.findUserByUsername(username);
    // 判断网络是否连通着的
    if (!isNetWorking(map)) {
      return false;
    }
    // 判断是否插入key
    if (!isExistKey(map, user, key)) {
      return false;
    }
    // // 使用用户的手机号码进行短信验证
    // if (!isShortMessageCheck(map, user, code)) {
    // return false;
    // }
    // 验证通过修改首次登陆状态以及授权时间和过期时间的设定
    if (!updateFirstLogin(map, user)) {
      return false;
    }
    // 绑定设备
    if (!bindDevice(map, user, bindDevice, bindDeviceName)) {
      return false;
    }
    return true;
  }

  @Override
  public boolean authorizationCodeNoBindCheck(Map<String, Object> map, String username,
      String code) {
    // 获取登陆对象
    User user = userQueryImpl.findUserByUsername(username);
    // 判断网络是否连通着的
    if (!isNetWorking(map)) {
      return false;
    }
    // 使用用户的手机号码进行短信验证
    if (!isShortMessageCheck(map, user, code)) {
      return false;
    }
    // 验证通过修改首次登陆状态以及授权时间和过期时间的设定
    if (!updateFirstLogin(map, user)) {
      return false;
    }
    return true;
  }

  @Override
  public boolean authorizationCodeBindCheck(Map<String, Object> map, String username, String code,
      String bindDevice, String bindDeviceName) {
    // 获取登陆对象
    User user = userQueryImpl.findUserByUsername(username);
    // 判断网络是否连通着的
    if (!isNetWorking(map)) {
      return false;
    }
    // // 使用用户的手机号码进行短信验证
    // if (!isShortMessageCheck(map, user, code)) {
    // return false;
    // }
    // 验证通过修改首次登陆状态以及授权时间和过期时间的设定
    if (!updateFirstLogin(map, user)) {
      return false;
    }
    // 绑定设备
    if (!bindDevice(map, user, bindDevice, bindDeviceName)) {
      return false;
    }
    return true;
  }

  /*
   * 判断网络是否正常工作
   */
  public boolean isNetWorking(Map<String, Object> map) {
    boolean netWork = true;
    if (!netWork) {
      map.put("status", "netBreaked");
      map.put("desc", "无法连接网络，请确保网络畅通。");
      return false;
    }
    return true;
  }

  /*
   * 1.判断key是否插入 2.判断key读出来的值是否与用户的保存的labId相等
   */
  public boolean isExistKey(Map<String, Object> map, User user, String key) {
    if (ValidateUtil.isEmpty(key)||"null".equals(key)) {
      map.put("desc", "系统未检测到U盾，请插入U盾。");
      map.put("status", "noKey");
      map.put("code", Constant.CODE_ERROR);
      return false;
    }
    // 判断key的值是否和user的layId相等
    if (!key.equals(user.getLabId())) {
      map.put("desc", "此U盾不是当前用户的U盾。");
      map.put("status", "keyValueNoEquels");
      map.put("code", Constant.CODE_ERROR);
      return false;
    }
    return true;
  }

  /*
   * 短信验证码验证
   */
  public boolean isShortMessageCheck(Map<String, Object> map, User user, String code) {
    SmsVerification sv = new SmsVerification();
    String result = sv.verifyCode(user.getMobile(), code);
    ShortMessage shortMessage = parseShortMessage(result);
    if (!Constant.SHORT_MESSAGE_CODE_000001.equals(shortMessage.getCode())) {
      map.put("status", "messageCheckFail");
      map.put("desc", shortMessage.getMessage());
      map.put("code", Constant.CODE_ERROR);
      return false;
    }
    return true;
  }

  /*
   * 1.修改tb_ca根据labId查找到的ca对象，授权生效时间和过期时间的设定 2.更新首次登陆状态
   * 
   */
  public boolean updateFirstLogin(Map<String, Object> map, User user) {
    user.setIsFirstLogin(Constant.USER_IS_FIRST_LOGIN_NO);
    userRepository.save(user);
    map.put("desc", "授权验证通过");
    map.put("code", Constant.CODE_SUCCESS);
    map.put("status", "authSuccess");
    return true;
  }

  /*
   * 绑定设备
   */
  public boolean bindDevice(Map<String, Object> map, User user, String bindDevice,
      String bindDeviceName) {
    user.setBindDevice(bindDevice);
    user.setBindDeviceName(bindDeviceName);
    user.setBindTime(new Date().getTime());
    userRepository.save(user);
    map.put("code", Constant.CODE_SUCCESS);
    map.put("desc", "绑定设备成功");
    map.put("status", "bindDeviceSuccess");
    return true;
  }

  /*
   * 解析成shortMessage对象
   */
  public ShortMessage parseShortMessage(String result) {
    return (ShortMessage) JsonUtil.toObject(result, ShortMessage.class);
  }

  @Override
  public boolean isOverAuthTime(Map<String, Object> map, String username) {
    // 获取登陆对象
    User user = userQueryImpl.findUserByUsername(username);
    if (user.getRole().equals("SYSADMIN")
        || Constant.USER_IS_FIRST_LOGIN_YES.equals(user.getIsFirstLogin())
        || Constant.USER_IS_FIRST_LOGIN_YES.equals(user.getIsUpdateDefaultPwd())) {
      map.put("overAutuTimedesc", "");
      map.put("overAutuTimestatus", "");
      return true;
    }
    List<Ca> cas = caQueryRepositoryImpl.findByParam("labId", user.getLabId());
    Ca ca = null;
    if (cas != null && !cas.isEmpty()) {
      ca = cas.get(0);
    }
    long day = (ca.getAuthEndTime() - new Date().getTime()) / (1000 * 24 * 60 * 60);
    if (day <= 30 && day > 0) {
      map.put("overAutuTimedesc", "授权将于" + day + "天后过期，请尽快续费。");
      map.put("overAutuTimestatus", "authOverTime");
    } else if (day <= 0) {
      map.put("overAutuTimedesc", "授权已过期，请续费。");
      map.put("overAutuTimestatus", "authOver");
    } else {
      map.put("overAutuTimedesc", "");
      map.put("overAutuTimestatus", "");
    }
    return true;
  }

  @Override
  public boolean isOverCapacity(Map<String, Object> map, String username) {
    // 获取登陆对象
    User user = userQueryImpl.findUserByUsername(username);
    String role = user.getRole();
    String spaceSize = user.getSpaceSize();
    String spaceCapacity = user.getSpaceCapacity();
    int noUsedCapacity = 0;
    if (role.equals("SYSADMIN")) {
      map.put("overCapacitydesc", "");
      map.put("overCapacitystatus", "");
      return true;
    }
    if ("ADMIN".equals(role)) {
      noUsedCapacity = Integer.valueOf(spaceSize) - Integer.valueOf(spaceCapacity);
    }
    if ("USER".equals(role)) {
      noUsedCapacity = Integer.valueOf(spaceSize) - Integer.valueOf(spaceCapacity);
    }
    if (noUsedCapacity < 0.2 * Integer.valueOf(spaceSize)) {
      map.put("overCapacitydesc", "当前用户的剩余容量已达" + noUsedCapacity + ",请及时扩充容量");
      map.put("overCapacitystatus", "overCapacity");
    } else {
      map.put("overCapacitydesc", "");
      map.put("overCapacitystatus", "");
    }
    return true;
  }
}
